﻿using LunarSF.SHomeWorkshop.LunarMarkdownEditor;
using SHomeWorkshop.LunarMind;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Xml;

namespace LunarSF.SHomeWorkshop.LunarMind
{

    /// <summary>
    /// 注意：不能直接使用 LME 中对应的文件。
    /// 此文件来改自 LunarMarkdownEditor ，用于在 LunarMind 中链接同名工作区中的相关资源。
    /// 工作区管理器中的条目。
    /// </summary>
    public class WorkspaceTreeViewItem : TreeViewItem
    {
        static WorkspaceTreeViewItem()
        {
            fileBitmapImage = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/Resources/Images/DocumentHS.png"));
            directoryBitmapImage = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/Resources/Images/FolderHS.png"));
            pictureImage = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/Resources/Images/PictureHS.png"));
            folderDocumentImage = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/Resources/Images/FolderDocument.png"));
            imageFolderImage = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/Resources/Images/ImageFolder.png"));
            soundImage = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/Resources/Images/sound.png"));
            soundFolderImage = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/Resources/Images/soundFolderImage.png"));
            vedioImage = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/Resources/Images/vedio.png"));
            vedioFolderImage = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/Resources/Images/vedioFolderImage.png"));
            homeImage = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/Resources/Images/home.png"));

            for (int i = 1; i <= 42; i++)
            {
                // 1-8 适用于文件夹；9－42适用于普通文件
                chmImages.Add(new BitmapImage(new Uri($"pack://application:,,,/LunarMind;component/Resources/Images/ChmIcons/{i.ToString("D2")}.png")));
            }
        }

        public enum Type
        {
            File,               //Markdown文件节点
            Folder,             //文件夹节点
            MetaFile,           //目录元文件节点
            Image,              //图像文件节点
            ImageFolder,        //Images~目录节点
            Sound,              //音频文件节点
            SoundFolder,        //Sounds~目录节点 
            Vedio,              //视频文件节点
            VedioFolder,        //Vedios~目录节点
        }

        private int chmImageIndex = 0;  // 默认值为 0 ，表示自动。其余取值为 1－42。
        /// <summary>
        /// 微软在 CHM 文件中，只支持42种内置图标。其中 1-8 适用于文件夹；9－42适用于普通文件。
        /// </summary>
        public int ChmImageIndex
        {
            get { return chmImageIndex; }
            set
            {
                if (value >= 0 && value <= 42)
                {
                    chmImageIndex = value;
                }
            }
        }

        /// <summary>
        /// 表示此文件或目录是否被标记为“已废弃”。
        /// </summary>
        public bool IsAborted
        {
            get
            {
                string filePath = null;
                if (this.IsMarkdownFilePath) filePath = this.fullPath;
                else if (this.IsDirectoryExists)
                {
                    if (this.FullPath.EndsWith("~") == false && this.FullPath.EndsWith("~\\") == false)
                    {
                        filePath = Globals.MainWindow.WorkspaceManager.GetMetaFilePathOfDirectory(this.FullPath);
                    }
                }

                if (filePath == null) return false;

                var isAbortedFile = WorkspaceManager.IsFileAborted(filePath);
                return isAbortedFile;
            }
        }

        /// <summary>
        /// 该文件是否被加密。
        /// </summary>
        public bool IsEncrypted
        {
            get
            {
                string filePath = null;
                if (this.IsMarkdownFilePath) filePath = this.fullPath;
                else if (this.IsDirectoryExists)
                {
                    if (this.FullPath.EndsWith("~") == false && this.FullPath.EndsWith("~\\") == false)
                    {
                        filePath = Globals.MainWindow.WorkspaceManager.GetMetaFilePathOfDirectory(this.FullPath);
                    }
                }

                if (filePath == null) return false;

                string password, passwordTip;
                return WorkspaceManager.IsFileEncrypted(filePath, out password, out passwordTip);
            }
        }

        /// <summary>
        /// 节点类型。
        /// </summary>
        public Type ItemType { get; set; }

        /// <summary>
        /// 节点Title左侧表示文件完成进度的文本。
        /// </summary>
        public string StatuHeader
        {
            get { return this.statusHeader == null ? "" : this.statusHeader; }
            set { this.statusHeader = value; }
        }

        /// <summary>
        /// 表示文件完成状态的注释文本。
        /// </summary>
        public string StatuTail
        {
            get { return this.statusTail == null ? "" : this.statusTail; }
            set { this.statusTail = value; }
        }

        /// <summary>
        /// 图像文件图标。
        /// </summary>
        static BitmapImage pictureImage;
        /// <summary>
        /// Markdown 文件图标。
        /// </summary>
        static BitmapImage fileBitmapImage;
        /// <summary>
        /// Markdown 文件图标。
        /// </summary>
        public static BitmapImage FileBitmapImage
        {
            get { return fileBitmapImage; }
        }
        /// <summary>
        /// 目录（文件夹）图标。
        /// </summary>
        static BitmapImage directoryBitmapImage;
        /// <summary>
        /// 目录文件组合图标。
        /// </summary>
        static BitmapImage folderDocumentImage;
        /// <summary>
        /// 目录文件组合图标。
        /// </summary>
        public static BitmapImage FolderDocumentImage
        {
            get { return folderDocumentImage; }
        }

        /// <summary>
        /// 图像资源文件夹图标。
        /// </summary>
        static BitmapImage imageFolderImage;

        /// <summary>
        /// 声音资源文件夹图标。
        /// </summary>
        static BitmapImage soundFolderImage;
        /// <summary>
        /// 声音资源图标。
        /// </summary>
        static BitmapImage soundImage;

        /// <summary>
        /// 视频资源文件夹图标。
        /// </summary>
        static BitmapImage vedioFolderImage;
        /// <summary>
        /// 视频资源图标。
        /// </summary>
        static BitmapImage vedioImage;

        /// <summary>
        /// 设定为 CHM 文件首页的的话，就显示这个图标。
        /// </summary>
        static BitmapImage homeImage;

        private static List<BitmapImage> chmImages = new List<BitmapImage>();
        /// <summary>
        /// CHM 自定义图标列表.其中，0－8用于文件夹，9－42用于文件。
        /// </summary>
        public static List<BitmapImage> ChmImage
        {
            get { return chmImages; }
        }

        private Brush foregroundOfText = Brushes.Black;
        /// <summary>
        /// 文本前景色。
        /// </summary>
        public Brush ForegroundOfText { get { return foregroundOfText; } }

        private bool isExcluded = false;
        /// <summary>
        /// 提供这个属性是为了允许用户阻止某些文件被编译到CHM中。默认为false。
        /// </summary>
        public bool IsExcluded
        {
            get { return this.isExcluded; }
            set
            {
                this.isExcluded = value;
            }
        }

        private bool isHomePage = false;
        /// <summary>
        /// 是否此页应作为CHM首页。
        /// </summary>
        public bool IsHomePage
        {
            get { return this.isHomePage; }
            set
            {
                this.isHomePage = value;
                RefreshIcon();
            }
        }

        /// <summary>
        /// 只作用于普通目录（带元文件）或普通 Markdown 文件条目。
        /// </summary>
        public void RefreshIcon()
        {
            switch (ItemType)
            {
                case Type.File:
                    {
                        if (isHomePage)
                        {
                            this.icon.Source = homeImage;
                            this.icon.ToolTip = "已设置为 CHM 工程首页";
                        }
                        else
                        {
                            if (chmImageIndex == 0)
                            {
                                this.icon.Source = chmImages[8];  // 第9个图标带问号的文档图标，是默认的。
                            }
                            else
                            {
                                this.icon.Source = ChmImage[chmImageIndex - 1];
                            }
                            this.icon.ToolTip = null;
                        }
                        break;
                    }
                case Type.Folder:
                case Type.MetaFile:
                    {
                        if (isHomePage)
                        {
                            this.icon.Source = homeImage;
                            this.icon.ToolTip = "已设置为 CHM 工程首页";
                        }
                        else
                        {
                            if (chmImageIndex <= 0 || chmImageIndex >= 43)
                            {
                                if (IsExpanded)
                                {
                                    this.icon.Source = chmImages[1];  // 第2个，展开的书本图标。
                                }
                                else this.icon.Source = chmImages[0];  // 第1个，关闭的书本图标。
                            }
                            else
                            {
                                if (this.IsExpanded)
                                {
                                    var index = chmImageIndex;
                                    if (chmImageIndex % 2 == 1)  // 总是奇数为合上，偶数为展开
                                    {
                                        this.icon.Source = chmImages[index];
                                    }
                                    else
                                    {
                                        this.icon.Source = chmImages[index - 1];
                                    }
                                }
                                else
                                {
                                    if (chmImageIndex % 2 == 1)
                                    {
                                        this.icon.Source = chmImages[chmImageIndex - 1];
                                    }
                                    else
                                    {
                                        this.icon.Source = chmImages[chmImageIndex - 2];
                                    }
                                }
                                //this.icon.Source = ChmImage[chmImageIndex - 1];
                            }
                            this.icon.ToolTip = null;
                        }
                        break;
                    }
            }
        }

        /// <summary>
        /// 用于树型列表框中各条目在选中时的边框色。
        /// </summary>
        //public static Brush TreeViewItemBorderBrush = new SolidColorBrush(Color.FromArgb(255, 250, 160, 0));

        /// <summary>
        /// [构造方法]工作区管理器条目。
        /// </summary>
        /// <param name="fullPath">指向的对象文件的完整磁盘路径。</param>
        /// <param name="masterWindow">主窗口。</param>
        public WorkspaceTreeViewItem(string fullPath, MainWindow masterWindow)
        {
            this.fullPath = fullPath;
            if (Directory.Exists(this.fullPath))
            {
                if (this.fullPath.EndsWith("\\") == false)
                {
                    this.fullPath += "\\";
                }
            }

            this.masterWindow = masterWindow;
            this.BorderThickness = new Thickness(1);
            this.Padding = new Thickness(2);
            this.SnapsToDevicePixels = true;
            this.showTitle = true;

            this.headerPanel.Children.Add(this.icon);
            this.headerPanel.Children.Add(this.headerTextBlock);
            this.Header = this.headerPanel;

            if (IsImageFileExist)
            {
                this.icon.Source = pictureImage;
                this.ItemType = Type.Image;
                var tpTextBlock = new TextBlock() { FontFamily = toolTipFontFamily, FontSize = 14, MaxWidth = 400, TextWrapping = TextWrapping.Wrap, };
                tpTextBlock.Inlines.Add(new Span(new Run("[图像资源文件]")) { FontWeight = FontWeights.Bold, });
                tpTextBlock.Inlines.Add(new LineBreak());
                tpTextBlock.Inlines.Add("单击预览，双击在文档中添加引用");
                this.ToolTip = tpTextBlock;

                //this.ToolTip = "单击预览，双击在文档中添加引用";
            }
            else if (IsSoundFileExist)
            {
                this.icon.Source = soundImage;
                this.ItemType = Type.Sound;

                var tpTextBlock = new TextBlock() { FontFamily = toolTipFontFamily, FontSize = 14, MaxWidth = 400, TextWrapping = TextWrapping.Wrap, };
                tpTextBlock.Inlines.Add(new Span(new Run("[音频资源文件]")) { FontWeight = FontWeights.Bold, });
                tpTextBlock.Inlines.Add(new LineBreak());
                tpTextBlock.Inlines.Add("单击预览，双击在文档中添加引用");
                this.ToolTip = tpTextBlock;

                //this.ToolTip = "单击预览，双击在文档中添加引用";
            }
            else if (IsVedioFileExist)
            {
                this.icon.Source = vedioImage;
                this.ItemType = Type.Vedio;

                var tpTextBlock = new TextBlock() { FontFamily = toolTipFontFamily, FontSize = 14, MaxWidth = 400, TextWrapping = TextWrapping.Wrap, };
                tpTextBlock.Inlines.Add(new Span(new Run("[视频资源文件]")) { FontWeight = FontWeights.Bold, });
                tpTextBlock.Inlines.Add(new LineBreak());
                tpTextBlock.Inlines.Add("单击预览，双击在文档中添加引用");
                this.ToolTip = tpTextBlock;

                //this.ToolTip = "单击预览，双击在文档中添加引用";
            }
            else if (IsDirectoryExists)
            {
                headerTextBlock.FontWeight = FontWeights.Bold;

                if (IsImageResourceDirectory)
                {
                    headerTextBlock.Foreground = foregroundOfText = Brushes.DimGray;
                    this.icon.Source = imageFolderImage;
                    this.ItemType = Type.ImageFolder;
                }
                else if (IsSoundResourceDirectory)
                {
                    headerTextBlock.Foreground = foregroundOfText = Brushes.DimGray;
                    this.icon.Source = soundFolderImage;
                    this.ItemType = Type.SoundFolder;
                }
                else if (IsVedioResourceDirectory)
                {
                    headerTextBlock.Foreground = foregroundOfText = Brushes.DimGray;
                    this.icon.Source = vedioFolderImage;
                    this.ItemType = Type.VedioFolder;
                }
                else
                {
                    headerTextBlock.Foreground = foregroundOfText = Brushes.Black;
                    //this.icon.Source = directoryBitmapImage;
                    this.ItemType = Type.Folder;

                    RefreshIcon();

                    DirectoryInfo di = new DirectoryInfo(FullPath);
                    var metaFilePath = (di.FullName.EndsWith("\\") ? di.FullName : (di.FullName + "\\")) + "_" + di.Name + ".md";

                    //只有普通目录才需要这个。
                    if (fullPath == Globals.PathOfWorkspace)
                    {
                        var tpTextBlock = new TextBlock() { FontFamily = toolTipFontFamily, FontSize = 14, MaxWidth = 400, TextWrapping = TextWrapping.Wrap, };
                        tpTextBlock.Inlines.Add(new Span(new Run("[目录]")) { FontWeight = FontWeights.Bold, });
                        tpTextBlock.Inlines.Add(new LineBreak());
                        tpTextBlock.Inlines.Add("工作区目录");
                        this.ToolTip = tpTextBlock;

                        //this.ToolTip = "工作区目录";
                    }
                    else
                    {
                        var tpTextBlock = new TextBlock() { FontFamily = toolTipFontFamily, FontSize = 14, MaxWidth = 400, TextWrapping = TextWrapping.Wrap, };
                        tpTextBlock.Inlines.Add(new Span(new Run("[目录]")) { FontWeight = FontWeights.Bold, });
                        tpTextBlock.Inlines.Add(new LineBreak());
                        tpTextBlock.Inlines.Add(this.FullPath);
                        this.ToolTip = tpTextBlock;

                        //this.ToolTip = this.FullPath;
                    }
                }
            }
            else if (IsValidateFilePath)
            //if(IsMarkdownFilePath)
            {
                if (IsFolderDocument)
                {
                    //this.icon.Source = folderDocumentImage;
                    this.ItemType = Type.MetaFile;
                }
                else
                {
                    //this.icon.Source = fileBitmapImage;
                    this.ItemType = Type.File;
                }

                RefreshIcon();

                var tpTextBlock = new TextBlock() { FontFamily = toolTipFontFamily, FontSize = 14, MaxWidth = 400, TextWrapping = TextWrapping.Wrap, };
                tpTextBlock.Inlines.Add(new Span(new Run("[MD文件]")) { FontWeight = FontWeights.Bold, });
                tpTextBlock.Inlines.Add(new LineBreak());
                tpTextBlock.Inlines.Add(this.FullPath);
                this.ToolTip = tpTextBlock;

                //this.ToolTip = this.FullPath;
            }

            this.headerTextBlock.Inlines.Add(fileStatusSpan);
            this.headerTextBlock.Inlines.Add(splitterSpan);
            this.headerTextBlock.Inlines.Add(titleOrShortNameSpan);

            this.titleOrShortNameSpan.MouseEnter += TitleOrShortNameSpan_MouseEnter;
            this.titleOrShortNameSpan.MouseLeave += TitleOrShortNameSpan_MouseLeave;

            //改成从文件中读取标题文本。
            RefreshFileState(); //含调用ShowHeaderText();

            this.Background = Brushes.Transparent;

            this.Expanded += WorkspaceTreeViewItem_Expanded;
            this.Collapsed += WorkspaceTreeViewItem_Collapsed;
        }

        private void WorkspaceTreeViewItem_Collapsed(object sender, RoutedEventArgs e)
        {
            if (IsDirectoryExists)
                RefreshIcon();
        }

        private void WorkspaceTreeViewItem_Expanded(object sender, RoutedEventArgs e)
        {
            if (IsDirectoryExists)
                RefreshIcon();
        }

        private FontFamily toolTipFontFamily = new FontFamily("Arial,SimSun");

        /// <summary>
        /// 
        /// 这个构造用于已经知道各参数的情况下直接构造——避免再读取硬盘。
        /// </summary>
        /// <param name="title"></param>
        /// <param name="path"></param>
        /// <param name="statusHeader"></param>
        /// <param name="statusTail"></param>
        /// <param name="tooltip"></param>
        /// <param name="itemType"></param>
        /// <param name="masterWindow"></param>
        public WorkspaceTreeViewItem(string title, string path, string statusHeader,
            string statusTail, string tooltip, bool isHomePage,
            Type itemType, int chmImageIndex, MainWindow masterWindow)
        {
            this.title = title;
            this.fullPath = path;
            this.statusHeader = statusHeader;
            this.statusTail = statusTail;
            this.isHomePage = isHomePage;
            this.ItemType = itemType;
            this.chmImageIndex = chmImageIndex;
            this.masterWindow = masterWindow;

            if (Directory.Exists(this.fullPath))
            {
                if (this.fullPath.EndsWith("\\") == false)
                {
                    this.fullPath += "\\";
                }
            }

            this.BorderThickness = new Thickness(1);
            this.Padding = new Thickness(2);
            this.SnapsToDevicePixels = true;
            this.showTitle = true;

            this.headerPanel.Children.Add(this.icon);
            this.titleOrShortNameSpan.Inlines.Add(new Run(title));//这里的title也可能是短文件名。
            this.headerPanel.Children.Add(this.headerTextBlock);
            this.Header = this.headerPanel;

            //if (string.IsNullOrWhiteSpace(tooltip) == false)
            //{
            //    this.ToolTip = tooltip;
            //}

            switch (this.ItemType)
            {
                case Type.File:
                    {
                        if (isHomePage)
                        {
                            this.icon.Source = homeImage;
                        }
                        else
                        {
                            this.icon.Source = fileBitmapImage;
                        }
                        var tpTextBlock = new TextBlock() { FontFamily = toolTipFontFamily, FontSize = 14, MaxWidth = 400, TextWrapping = TextWrapping.Wrap, };
                        tpTextBlock.Inlines.Add(new Span(new Run("[MD文件]")) { FontWeight = FontWeights.Bold, });
                        tpTextBlock.Inlines.Add(new LineBreak());
                        tpTextBlock.Inlines.Add(this.FullPath);
                        this.ToolTip = tpTextBlock;
                        break;
                    }
                case Type.Folder:
                    {
                        headerTextBlock.FontWeight = FontWeights.Bold;
                        headerTextBlock.Foreground = foregroundOfText = Brushes.Black;
                        this.icon.Source = directoryBitmapImage;
                        if (fullPath == Globals.PathOfWorkspace)
                        {
                            if (isHomePage)
                            {
                                this.icon.Source = homeImage;
                            }
                            else
                            {
                                this.icon.Source = WorkspaceTreeViewItem.FolderDocumentImage;
                            }
                            var tpTextBlock = new TextBlock() { FontFamily = toolTipFontFamily, FontSize = 14, MaxWidth = 400, TextWrapping = TextWrapping.Wrap, };
                            tpTextBlock.Inlines.Add(new Span(new Run("[目录]")) { FontWeight = FontWeights.Bold, });
                            tpTextBlock.Inlines.Add(new LineBreak());
                            tpTextBlock.Inlines.Add("工作区目录");
                            this.ToolTip = tpTextBlock;

                            //this.ToolTip = "工作区目录";
                        }
                        else
                        {
                            if (isHomePage)
                            {
                                this.icon.Source = homeImage;
                            }
                            else
                            {
                                this.icon.Source = WorkspaceTreeViewItem.FolderDocumentImage;
                            }
                            var tpTextBlock = new TextBlock() { FontFamily = toolTipFontFamily, FontSize = 14, MaxWidth = 400, TextWrapping = TextWrapping.Wrap, };
                            tpTextBlock.Inlines.Add(new Span(new Run("[目录]")) { FontWeight = FontWeights.Bold, });
                            tpTextBlock.Inlines.Add(new LineBreak());
                            tpTextBlock.Inlines.Add(this.FullPath);
                            this.ToolTip = tpTextBlock;

                            //this.ToolTip = this.FullPath;
                        }
                        break;
                    }
                case Type.MetaFile:   //实际上 MetaFile 在工作区管理器中总是表现为 Folder。
                    {
                        if (isHomePage)
                        {
                            this.icon.Source = homeImage;
                        }
                        else
                        {
                            this.icon.Source = folderDocumentImage;
                        }
                        break;
                    }
                case Type.Image:
                    {
                        this.icon.Source = pictureImage;
                        var tpTextBlock = new TextBlock() { FontFamily = toolTipFontFamily, FontSize = 14, MaxWidth = 400, TextWrapping = TextWrapping.Wrap, };
                        tpTextBlock.Inlines.Add(new Span(new Run("[图像资源文件]")) { FontWeight = FontWeights.Bold, });
                        tpTextBlock.Inlines.Add(new LineBreak());
                        tpTextBlock.Inlines.Add("单击预览，双击在文档中添加引用");
                        this.ToolTip = tpTextBlock;
                        break;
                    }
                case Type.ImageFolder:
                    {
                        this.icon.Source = imageFolderImage;
                        headerTextBlock.FontWeight = FontWeights.Bold;
                        headerTextBlock.Foreground = foregroundOfText = Brushes.DimGray;

                        var tpTextBlock = new TextBlock() { FontFamily = toolTipFontFamily, FontSize = 14, MaxWidth = 400, TextWrapping = TextWrapping.Wrap, };
                        tpTextBlock.Inlines.Add(new Span(new Run("[图像资源目录]")) { FontWeight = FontWeights.Bold, });
                        this.ToolTip = tpTextBlock;

                        break;
                    }
                case Type.Sound:
                    {
                        this.icon.Source = soundImage;
                        var tpTextBlock = new TextBlock() { FontFamily = toolTipFontFamily, FontSize = 14, MaxWidth = 400, TextWrapping = TextWrapping.Wrap, };
                        tpTextBlock.Inlines.Add(new Span(new Run("[音频资源文件]")) { FontWeight = FontWeights.Bold, });
                        tpTextBlock.Inlines.Add(new LineBreak());
                        tpTextBlock.Inlines.Add("单击预览，双击在文档中添加引用");
                        this.ToolTip = tpTextBlock;
                        break;
                    }
                case Type.SoundFolder:
                    {
                        this.icon.Source = soundFolderImage;
                        headerTextBlock.FontWeight = FontWeights.Bold;
                        headerTextBlock.Foreground = foregroundOfText = Brushes.DimGray;

                        var tpTextBlock = new TextBlock() { FontFamily = toolTipFontFamily, FontSize = 14, MaxWidth = 400, TextWrapping = TextWrapping.Wrap, };
                        tpTextBlock.Inlines.Add(new Span(new Run("[音频资源目录]")) { FontWeight = FontWeights.Bold, });
                        this.ToolTip = tpTextBlock;

                        break;
                    }
                case Type.Vedio:
                    {
                        this.icon.Source = vedioImage;
                        var tpTextBlock = new TextBlock() { FontFamily = toolTipFontFamily, FontSize = 14, MaxWidth = 400, TextWrapping = TextWrapping.Wrap, };
                        tpTextBlock.Inlines.Add(new Span(new Run("[视频资源文件]")) { FontWeight = FontWeights.Bold, });
                        tpTextBlock.Inlines.Add(new LineBreak());
                        tpTextBlock.Inlines.Add("单击预览，双击在文档中添加引用");
                        this.ToolTip = tpTextBlock;

                        break;
                    }
                case Type.VedioFolder:
                    {
                        this.icon.Source = vedioFolderImage;
                        headerTextBlock.FontWeight = FontWeights.Bold;
                        headerTextBlock.Foreground = foregroundOfText = Brushes.DimGray;

                        var tpTextBlock = new TextBlock() { FontFamily = toolTipFontFamily, FontSize = 14, MaxWidth = 400, TextWrapping = TextWrapping.Wrap, };
                        tpTextBlock.Inlines.Add(new Span(new Run("[视频资源目录]")) { FontWeight = FontWeights.Bold, });
                        this.ToolTip = tpTextBlock;

                        break;
                    }
            }

            //if (IsDirectoryExists)
            //{
            //    if (fullPath == Globals.PathOfWorkspace)
            //    {
            //        this.ToolTip = "工作区目录";
            //    }
            //    else
            //    {
            //        this.ToolTip = this.FullPath;
            //    }

            //    DirectoryInfo di = new DirectoryInfo(FullPath);
            //    var metaFilePath = (di.FullName.EndsWith("\\") ? di.FullName : (di.FullName + "\\")) + "_" + di.Name + ".md";
            //}

            this.headerTextBlock.Inlines.Add(fileStatusSpan);
            this.headerTextBlock.Inlines.Add(splitterSpan);
            this.headerTextBlock.Inlines.Add(titleOrShortNameSpan);
            this.titleOrShortNameSpan.MouseEnter += TitleOrShortNameSpan_MouseEnter;
            this.titleOrShortNameSpan.MouseLeave += TitleOrShortNameSpan_MouseLeave;

            //改成从文件中读取标题文本。
            this.RefreshFileStateByHeader(statusHeader, statusTail);

            //刷新图标啥的。
            RefreshIcon();

            this.Background = Brushes.Transparent;

            this.Expanded += WorkspaceTreeViewItem_Expanded;
            this.Collapsed += WorkspaceTreeViewItem_Collapsed;
            //this.LostFocus += WorkspaceTreeViewItem_LostFocus;  // 这个不起作用

            this.PreviewMouseLeftButtonDown += WorkspaceTreeViewItem_PreviewMouseLeftButtonDown;
        }

        private void WorkspaceTreeViewItem_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2)
            {
                // 注意 TreeView 双击时，会按上层的 TreeViewItem 而改用 MouseLeftButton 又不起作用。
                if (Globals.MainWindow.tvWorkDirectory.Items.Count <= 0) return;

                var activeWtiv = Globals.MainWindow.tvWorkDirectory.Items[0] as WorkspaceTreeViewItem;
                if (activeWtiv == null) return;

                if (activeWtiv.IsSelected)
                {
                    Globals.MainWindow.InsertTitleImage(null, activeWtiv.FullPath);
                }
                else
                {
                    activeWtiv = GetActiveWorkspaceTreeViewItem(activeWtiv);
                    if(activeWtiv != null)
                    {
                        Globals.MainWindow.InsertTitleImage(null, activeWtiv.FullPath);
                    }
                }

                e.Handled = true;
            }
        }

        private WorkspaceTreeViewItem GetActiveWorkspaceTreeViewItem(WorkspaceTreeViewItem wtvi)
        {
            if (wtvi == null) return null;

            if (wtvi.IsSelected) return wtvi;

            if(wtvi.Items .Count > 0)
            {
                foreach(var subi in wtvi.Items)
                {
                    var subwtvi = subi as WorkspaceTreeViewItem;
                    if (subwtvi == null) continue;

                    if (subwtvi.IsSelected) return subwtvi;

                    GetActiveWorkspaceTreeViewItem(subwtvi);
                }
            }

            return null;
        }

        private void TitleOrShortNameSpan_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            this.titleOrShortNameSpan.Background = Brushes.Transparent;
        }

        private void TitleOrShortNameSpan_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            this.titleOrShortNameSpan.Background = Brushes.WhiteSmoke;
        }

        /// <summary>
        /// 取文件的注释短名。
        /// 当图像文件为中文文件名时，编译为 CHM 易出现问题，而英文又不够直观。
        /// 所以，考虑直接将图像文件命名为拼音（纯英文字母即可），
        /// 然后在一个单独的纯文本文件中记录这些英文字母对应的中文短名。
        /// 
        /// 注意：此备注文件中同一文件短名可能存在多行备注，以最后一个为准。例如：
        /// 
        /// tp1.png|图片1.png
        /// tp2.png|图片2.png
        /// tp1.png|图片1新名称.png
        /// 
        /// 此时返回的会是“图片1新名称.png”。也就是说“后一个会覆盖前一个”。
        /// </summary>
        /// <param name="filePath">通常应传入图像文件的完整路径。</param>
        public static string GetCommentShortName(string filePath)
        {
            if (File.Exists(filePath))
            {
                FileInfo fi = new FileInfo(filePath);
                var commentFilePath = fi.DirectoryName + "\\" + "~.txt";
                if (File.Exists(commentFilePath) == false) return fi.Name;

                var lines = File.ReadAllLines(commentFilePath, Encoding.UTF8);
                var splitter = new char[] { '|' };
                for (int i = lines.Length - 1; i >= 0; i--)
                {
                    var line = lines[i];
                    if (line.StartsWith(";") || line.StartsWith("；") || line.StartsWith("/")) continue;

                    var spans = line.Split(splitter, StringSplitOptions.RemoveEmptyEntries);
                    if (spans.Length != 2) continue;

                    if (spans[0] == fi.Name) return spans[1];
                }

                return fi.Name;
            }

            return "";
        }

        /// <summary>
        /// 根据 “ShowTitle”刷新。如果“ShowTitle”为真，尝试显示文档中设置的文档标题；否则直接显示文件短名。
        /// </summary>
        private void ShowHeaderText()
        {
            this.titleOrShortNameSpan.Inlines.Clear();

            if (showTitle)
            {
                if (this.IsMarkdownFilePath)
                {
                    title = WorkspaceManager.GetTitleOfMdFile(this.fullPath);
                    if (string.IsNullOrWhiteSpace(title) == false)
                    {
                        this.titleOrShortNameSpan.Inlines.Add(new Run(title));
                    }
                    else
                    {
                        this.titleOrShortNameSpan.Inlines.Add(new Run(this.ShortName));
                    }
                }
                else if (this.IsDirectoryExists)
                {
                    DirectoryInfo di = new DirectoryInfo(this.fullPath);
                    if (di.Name.ToLower() == "images~")
                    {
                        this.titleOrShortNameSpan.Inlines.Add(new Run(title = "图像~"));
                    }
                    else if (di.Name.ToLower() == "sounds~")
                    {
                        this.titleOrShortNameSpan.Inlines.Add(new Run(title = "声音~"));
                    }
                    else if (di.Name.ToLower() == "vedios~")
                    {
                        this.titleOrShortNameSpan.Inlines.Add(new Run(title = "视频~"));
                    }
                    else
                    {
                        var metaFilePath = (di.FullName.EndsWith("\\") ? di.FullName : (di.FullName + "\\")) + "_" + di.Name + ".md";
                        if (File.Exists(metaFilePath))
                        {
                            var metaFileTitle = WorkspaceManager.GetTitleOfMdFile(metaFilePath);
                            if (string.IsNullOrWhiteSpace(metaFilePath) == false)
                            {
                                this.titleOrShortNameSpan.Inlines.Add(new Run(title = metaFileTitle));
                            }
                            else
                            {
                                this.titleOrShortNameSpan.Inlines.Add(new Run(title = this.ShortName));
                            }
                        }
                        else
                        {
                            this.titleOrShortNameSpan.Inlines.Add(new Run(title = this.ShortName));
                        }
                    }
                }
                else if (this.IsImageFileExist || this.IsSoundFileExist || this.IsVedioFileExist)
                {
                    this.titleOrShortNameSpan.Inlines.Add(new Run(title = GetCommentShortName(this.fullPath)));
                }
                else
                {
                    this.titleOrShortNameSpan.Inlines.Add(new Run(title = this.ShortName));
                }
            }
            else
            {
                this.titleOrShortNameSpan.Inlines.Add(new Run(title = this.ShortName));
            }
        }

        private bool showTitle = false;
        /// <summary>
        /// 为真时尝试显示在文件中设置的文档标题。否则直接显示文件短名。
        /// </summary>
        public bool ShowTitle
        {
            get { return showTitle; }
            set
            {
                showTitle = value;
                ShowHeaderText();
            }
        }

        /// <summary>
        /// 取当前项对应的资源文件夹的完整路径。
        /// </summary>
        public string ResourceDirectoryFullPath
        {
            get
            {
                if (IsMarkdownFilePath == false) return string.Empty;

                var parentDirectoryPath = this.fullPath.Substring(0, this.fullPath.LastIndexOf("\\") + 1);

                return parentDirectoryPath + ShortName.Substring(0, ShortName.Length - 3) + "~";
            }
        }

        /// <summary>
        /// 承载当前项名称文本、图标的 StackPanel。
        /// </summary>
        private StackPanel headerPanel = new StackPanel()
        {
            Orientation = Orientation.Horizontal,
            Margin = new Thickness(4, 0, 4, 0),
        };

        private static FontFamily fileStatusFontFamily = new FontFamily("SimSun");

        /// <summary>
        /// 用于显示文件完成状态标记。
        /// </summary>
        private Span fileStatusSpan = new Span() { FontFamily = fileStatusFontFamily };

        /// <summary>
        /// 用来分隔“文件完成状态标记”与“文件标题（或短名）标记”。
        /// </summary>
        private Span splitterSpan = new Span();

        /// <summary>
        /// 用以显示文档标题（或文件短名）。
        /// </summary>
        private Span titleOrShortNameSpan = new Span();

        private TextBlock headerTextBlock = new TextBlock()
        {
            FontSize = 14,
            Foreground = Brushes.Black,
            Padding = new Thickness(0, 2, 0, 2),
            VerticalAlignment = VerticalAlignment.Center,
        };
        /// <summary>
        /// 用于显示文件短名。
        /// </summary>
        public TextBlock HeaderTextBlock { get { return headerTextBlock; } }

        /// <summary>
        /// 用于显示条目类别图标。
        /// </summary>
        private Image icon = new Image() { Width = 16, Height = 16, Margin = new Thickness(0, 0, 2, 0), };

        /// <summary>
        /// IsMarkdownFilePath的别名。
        /// </summary>
        public bool IsValidateFilePath
        {
            get { return IsMarkdownFilePath; }
        }

        /// <summary>
        /// 是否合法的文本文件的路径。
        /// </summary>
        public bool IsMarkdownFilePath
        {
            get
            {
                if (string.IsNullOrEmpty(this.fullPath)) return false;

                if (File.Exists(this.fullPath) == false) return false;

                if (this.fullPath.ToLower().EndsWith(".md") == false) return false;

                if (this.fullPath.Length <= 4) return false;

                return true;
            }
        }

        /// <summary>
        /// 是否带元文件、并可以添加下级目录或文件的普通目录。
        /// 如果是资源目录则返回 false。
        /// </summary>
        public bool IsMetaDirectoryPath
        {
            get
            {
                if (IsDirectoryExists == false) return false;

                if (this.FullPath.EndsWith("~\\") || this.FullPath.EndsWith("~")) return false;

                return true;
            }
        }

        /// <summary>
        /// 如果不是普通目录（而是资源目录或文件），返回null。
        /// 如果是普通目录（带元文件），返回目录元文件的完整路径。
        /// </summary>
        public string MetaFilePath
        {
            get
            {
                if (IsMetaDirectoryPath == false) return null;

                DirectoryInfo di = new DirectoryInfo(this.FullPath);
                var path = (di.FullName.EndsWith("\\") ? di.FullName : (di.FullName + "\\")) + "_" + di.Name + ".md";
                return path;
            }
        }

        /// <summary>
        /// 如果不是普通目录（而是资源目录或文件），返回null。
        /// 如果是普通目录（带元文件），返回目录元文件编译成的 Html 的完整路径。
        /// </summary>
        public string MetaHtmlFilePath
        {
            get
            {
                if (IsMetaDirectoryPath == false) return null;

                DirectoryInfo di = new DirectoryInfo(this.FullPath);
                var path = (di.FullName.EndsWith("\\") ? di.FullName : (di.FullName + "\\")) + "_" + di.Name + ".html";
                return path;
            }
        }

        /// <summary>
        /// 是不是所在目录指向的特定文件，规则是：“_目录名.md”（“_目录名.html”）
        /// </summary>
        public bool IsFolderDocument
        {
            get
            {
                if (IsMarkdownFilePath == false) return false;

                if (File.Exists(this.fullPath) == false) return false;

                FileInfo fileInfo = new FileInfo(this.fullPath);
                if (fileInfo.Name.ToLower() == ("_" + fileInfo.Directory.Name + ".md").ToLower())
                {
                    return true;
                }

                return false;
            }
        }

        private string fullPath;
        /// <summary>
        /// 当前项指向的 Markdown 文件、图像文件、目录的完全路径。
        /// </summary>
        public string FullPath
        {
            get
            {
                if (IsDirectoryExists && this.fullPath.EndsWith("\\") == false)
                {
                    this.fullPath += "\\";
                }
                return this.fullPath;
            }
            set
            {
                this.fullPath = value;
                if (Directory.Exists(this.fullPath))
                {
                    if (this.fullPath.EndsWith("\\") == false)
                        this.fullPath += "\\";
                }
                this.RefreshFileState();
                this.ToolTip = this.fullPath;
            }
        }

        /// <summary>
        /// 当前项指向的 Markdown 文件、图像文件、目录的短名。
        /// </summary>
        public string ShortName
        {
            get
            {
                if (string.IsNullOrEmpty(this.fullPath))
                {
                    return string.Empty;
                }

                if (this.fullPath.EndsWith("\\"))//目录
                {
                    if (this.fullPath.Length < 2) return string.Empty;

                    int index = this.fullPath.LastIndexOf('\\', this.fullPath.Length - 2);//不取最后一个
                    if (index < 0) return this.fullPath.Substring(0, this.fullPath.Length - 1);

                    return this.fullPath.Substring(index + 1, this.fullPath.Length - index - 2);//不含反斜杠。
                }
                else
                {
                    int lastIndex = this.fullPath.LastIndexOf('\\');
                    if (lastIndex < 0) return this.fullPath;

                    return this.fullPath.Substring(lastIndex + 1);
                }
            }
        }

        /// <summary>
        /// 返回编译目标 Html 文件的短名。
        /// </summary>
        public string ShortHtmlName
        {
            get
            {
                var shortName = ShortName;
                if (string.IsNullOrEmpty(shortName)) return "";
                if (shortName.ToLower().EndsWith(".md"))
                    return shortName.Substring(0, shortName.Length - 3) + ".html";

                return shortName;
            }
        }

        /// <summary>
        /// 返回编译目标 Html 文件的完整路径。
        /// </summary>
        public string HtmlFullPath
        {
            get
            {
                if (this.fullPath.ToLower().EndsWith(".md"))
                {
                    return this.fullPath.Substring(0, this.fullPath.Length - 3) + ".html";
                }
                return this.fullPath;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public string RevealJsHtmlFullPath
        {
            get
            {
                if (this.fullPath.ToLower().EndsWith(".md"))
                {
                    return this.fullPath.Substring(0, this.fullPath.Length - 3) + "_tmp~.html";
                }
                return this.fullPath;
            }
        }

        private string title = "";
        /// <summary>
        /// 显示出来的标题文本。
        /// </summary>
        public string Title
        {
            get
            {
                return title;
            }
        }

        public string ImageTitle
        {
            get
            {
                if (string.IsNullOrWhiteSpace(title)) return "";
                if (title.ToLower().EndsWith(".png")) return title.Substring(0, title.Length - 4);
                if (title.ToLower().EndsWith(".jpg")) return title.Substring(0, title.Length - 4);
                if (title.ToLower().EndsWith(".jpeg")) return title.Substring(0, title.Length - 5);
                if (title.ToLower().EndsWith(".gif")) return title.Substring(0, title.Length - 4);
                if (title.ToLower().EndsWith(".ico")) return title.Substring(0, title.Length - 4);
                if (title.ToLower().EndsWith(".tiff")) return title.Substring(0, title.Length - 5);
                if (title.ToLower().EndsWith(".bmp")) return title.Substring(0, title.Length - 4);

                return title;
            }
        }

        /// <summary>
        /// 当前项指向的对象是否有效目录。
        /// </summary>
        public bool IsDirectoryExists
        {
            get { return Directory.Exists(this.fullPath); }
        }

        /// <summary>
        /// 当前项指向的对象是否有效的图像资源文件夹。
        /// </summary>
        public bool IsImageResourceDirectory
        {
            get
            {
                if (IsDirectoryExists == false) return false;

                DirectoryInfo directoryInfo = new DirectoryInfo(this.fullPath);
                if (directoryInfo.Name.ToLower() == "images~") return true;

                return false;
            }
        }

        /// <summary>
        /// 当前项指向的对象是否有效的声音资源文件夹。
        /// </summary>
        public bool IsSoundResourceDirectory
        {
            get
            {
                if (IsDirectoryExists == false) return false;

                DirectoryInfo directoryInfo = new DirectoryInfo(this.fullPath);
                if (directoryInfo.Name.ToLower() == "sounds~") return true;

                return false;
            }
        }

        /// <summary>
        /// 当前项指向的对象是否有效的视频资源文件夹。
        /// </summary>
        public bool IsVedioResourceDirectory
        {
            get
            {
                if (IsDirectoryExists == false) return false;

                DirectoryInfo directoryInfo = new DirectoryInfo(this.fullPath);
                if (directoryInfo.Name.ToLower() == "vedios~") return true;

                return false;
            }
        }

        /// <summary>
        /// 当前项指向的对象是否有效的图像资源文件。
        /// </summary>
        public bool IsImageFileExist
        {
            get
            {
                var b = IsValidateImageFilePath(this.fullPath);
                return b;
            }
        }

        /// <summary>
        /// 指定路径是否有效的图像文件路径。
        /// </summary>
        /// <param name="fullPath">要检查的图像文件路径。</param>
        public static bool IsValidateImageFilePath(string fullPath)
        {
            if (File.Exists(fullPath) == false) return false;
            var path = fullPath.ToLower();

            if (path.EndsWith(".bmp")) return true;
            else if (path.EndsWith(".ico")) return true;//可以支持
            else if (path.EndsWith(".png")) return true;
            else if (path.EndsWith(".gif")) return true;
            else if (path.EndsWith(".jpg")) return true;
            else if (path.EndsWith(".jpeg")) return true;
            else if (path.EndsWith(".tiff")) return true;

            return false;
        }

        /// <summary>
        /// 当前项指向的对象是否有效的声音资源文件。
        /// </summary>
        public bool IsSoundFileExist
        {
            get
            {
                var b = IsValidateSoundFilePath(this.fullPath);
                return b;
            }
        }

        /// <summary>
        /// 指定路径是否有效的声音文件路径。
        /// </summary>
        /// <param name="fullPath">要检查的声音文件路径。</param>
        /// <returns></returns>
        public static bool IsValidateSoundFilePath(string fullPath)
        {
            if (File.Exists(fullPath) == false) return false;
            var path = fullPath.ToLower();

            if (path.EndsWith(".mp3")) return true;
            else if (path.EndsWith(".wav")) return true;//可以支持
            else if (path.EndsWith(".wma")) return true;

            return false;
        }

        /// <summary>
        /// 当前项指向的对象是否有效的视频资源文件。
        /// </summary>
        public bool IsVedioFileExist
        {
            get
            {
                var b = IsValidateVedioFilePath(this.fullPath);
                return b;
            }
        }

        /// <summary>
        /// 指定路径是否有效的视频文件路径。
        /// </summary>
        /// <param name="fullPath">要检查的视频文件路径。</param>
        /// <returns></returns>
        public static bool IsValidateVedioFilePath(string fullPath)
        {
            if (File.Exists(fullPath) == false) return false;
            var path = fullPath.ToLower();

            if (path.EndsWith(".mp4")) return true;
            else if (path.EndsWith(".flv")) return true;//可以支持
            else if (path.EndsWith(".swf")) return true;

            return false;
        }

        /// <summary>
        /// 当前项指向的路径是否存在有效的文件。
        /// </summary>
        public bool IsFileExists
        {
            get { return File.Exists(this.fullPath); }
        }

        /// <summary>
        /// 当前项指向的路径是否有效的资源文件。
        /// </summary>
        public bool IsResourceFile
        {
            get
            {
                if (File.Exists(this.fullPath) == false) return false;

                int lastIndex = this.fullPath.LastIndexOf("\\");
                if (lastIndex < 0) return false;

                var s = this.fullPath.Substring(0, lastIndex);
                if (s.EndsWith("~") == false) return false;

                return true;
            }
        }

        /// <summary>
        /// 当前项指向的目录是否有效的资源目录。
        /// </summary>
        public bool IsResourceDirectory
        {
            get
            {
                if (Directory.Exists(this.fullPath) == false) return false;

                if (this.fullPath.EndsWith("~") || this.fullPath.EndsWith("~\\")) return true;

                return false;
            }
        }

        private MainWindow masterWindow;
        private string statusHeader;
        private string statusTail;

        /// <summary>
        /// 要用来打开文档，故需要保持此信息。
        /// </summary>
        public MainWindow MasterWindow { get { return this.masterWindow; } }

        /// <summary>
        /// 当前项指向的对象所在的上级目录。
        /// </summary>
        public string ParentDirectory
        {
            get
            {
                if (IsMarkdownFilePath)
                {
                    return this.fullPath.Substring(0, this.fullPath.LastIndexOf("\\") + 1);
                }
                else if (IsDirectoryExists)
                {
                    var path = this.fullPath;
                    if (path.EndsWith("\\")) path = path.Substring(0, path.Length - 1);
                    int lastIndex = path.LastIndexOf("\\");
                    if (lastIndex < 0) return null;

                    return path.Substring(0, lastIndex + 1);
                }

                return null;
            }
        }

        /// <summary>
        /// 当前项的父项。
        /// </summary>
        public WorkspaceTreeViewItem ParentWorkspaceTreeViewItem
        {
            get
            {
                if (this.Parent == null) return null;
                var parent = this.Parent as WorkspaceTreeViewItem;
                return parent;
            }
        }

        /// <summary>
        /// 这是相对工作区的路径。
        /// 例如：工作区目录是 C:\秦朝政制制度\
        /// 当前项的完全路径是 C:\秦朝政制制度\中央政制\皇帝制度\
        /// 则此属性的返回值是 中央政制\皇帝制度\
        /// </summary>
        public string RelativePath
        {
            get
            {
                var fullPathText = this.FullPath;
                if (string.IsNullOrWhiteSpace(fullPathText)) return "";

                var workspacePathText = Globals.PathOfWorkspace.ToLower();

                if (fullPathText.StartsWith(workspacePathText, StringComparison.CurrentCultureIgnoreCase))
                {
                    return fullPathText.Substring(workspacePathText.Length);
                }
                return "";
            }
        }

        /// <summary>
        /// 当项目不是个 Markdown 文件时，返回 RelativePath。
        /// 当项目是个 Markdown 文件时，返回的路径后缀名改为“.html”而不是“.md”，这是它和 RelativePath 唯一的区别。
        /// </summary>
        public string RelativeHtmlPath
        {
            get
            {
                var rp = this.RelativePath;
                if (string.IsNullOrWhiteSpace(rp)) return rp;

                if (rp.EndsWith(".md", StringComparison.CurrentCultureIgnoreCase))
                {
                    return rp.Substring(0, rp.Length - 3) + ".html";
                }

                if (rp.EndsWith("\\"))
                {
                    rp = Globals.MainWindow.WorkspaceManager.GetMetaFilePathOfDirectory(this.FullPath);
                    if (rp.EndsWith(".md", StringComparison.CurrentCultureIgnoreCase))
                    {
                        return rp.Substring(0, rp.Length - 3) + ".html";
                    }
                }

                return rp;
            }
        }

        /// <summary>
        /// 刷新当前 Markdown 或目录元文件的完成状态标志和标题（如果 Globals.MainWindow.ShowTitleInWorkspaceManager为true）。
        /// </summary>
        internal void RefreshFileState()
        {
            this.ShowHeaderText();

            if (Directory.Exists(fullPath))
            {
                var dimmm = new DirectoryInfo(fullPath);
                if (dimmm.Name.ToLower().EndsWith("~"))
                {
                    this.fileStatusSpan.Inlines.Clear();
                    return;
                }
            }

            var destFilePath = fullPath;

            if (File.Exists(fullPath) == false)
            {
                if (Directory.Exists(fullPath) == false)
                {
                    this.headerTextBlock.Inlines.Add(new Span(new Run(this.ShortName)));
                    return;
                }
                else
                {
                    DirectoryInfo di = new DirectoryInfo(fullPath);
                    var metaFilePath = (di.FullName.EndsWith("\\") ? di.FullName : (di.FullName + "\\")) + "_" + di.Name + ".md";
                    if (File.Exists(metaFilePath) == false)
                    {
                        this.fileStatusSpan.Inlines.Clear();

                        //实际上后一个是根本不会显示在工作区的。因为路径是这样的：ResourceDirectory~/Images~。
                        if (this.IsImageResourceDirectory || this.IsResourceDirectory)
                        {
                            this.fileStatusSpan.Inlines.Add(new Run(""));
                            this.StatuHeader = "";
                        }
                        else
                        {
                            this.fileStatusSpan.Inlines.Add(new Run("[-]"));
                            this.StatuHeader = "[-]";
                        }

                        this.fileStatusSpan.Background = Brushes.Red;
                        this.fileStatusSpan.Foreground = Brushes.White;
                        this.fileStatusSpan.FontWeight = FontWeights.Bold;
                        this.fileStatusSpan.ToolTip = "未开始";

                        this.splitterSpan.Inlines.Clear();
                        this.splitterSpan.Inlines.Add(new Run(" "));
                        return;
                    }

                    destFilePath = metaFilePath;
                }
            }

            if (this.IsImageFileExist ||
                this.IsSoundFileExist ||
                this.IsVedioFileExist)
            {
                this.fileStatusSpan.Inlines.Clear();
                return;
            }

            using (StreamReader sr = new StreamReader(destFilePath))
            {
                var fstLine = sr.ReadLine();
                if (fstLine != null && fstLine.Length >= 3)
                {
                    string header = "";
                    Regex regex = new Regex(@"\[[ 　\t]*[－\-\+＋\#＃\%％][ 　\t]*\]");
                    var tail = "";
                    var match = regex.Match(fstLine);
                    if (match.Success)
                    {
                        header = match.Value.Replace("－", "-").Replace("＋", "+").Replace("％", "%").Replace("＃", "#").Replace(" ", "").Replace("　", "").Replace("\t", "");
                        tail = " ◆ " + fstLine.Substring(match.Length).Trim(new char[] { ' ', '　', '\t' });
                    }

                    RefreshFileStateByHeader(header, tail);

                    this.StatuHeader = header;
                    this.StatuTail = tail;
                }
                else
                {
                    this.fileStatusSpan.Inlines.Clear();
                    this.fileStatusSpan.Inlines.Add(new Run("[-]"));
                    this.fileStatusSpan.Background = Brushes.Red;
                    this.fileStatusSpan.Foreground = Brushes.White;
                    this.fileStatusSpan.FontWeight = FontWeights.Bold;
                    this.fileStatusSpan.ToolTip = "未开始";

                    this.splitterSpan.Inlines.Clear();
                    this.splitterSpan.Inlines.Add(new Run(" "));
                }
            }
        }

        private void RefreshFileStateByHeader(string header, string tail)
        {
            switch (ItemType)
            {
                case Type.Image:
                case Type.ImageFolder:
                case Type.Sound:
                case Type.SoundFolder:
                case Type.Vedio:
                case Type.VedioFolder:
                    {
                        this.fileStatusSpan.Inlines.Clear();
                        return;
                    }
            }

            switch (header)
            {
                case "[%]":
                    {
                        this.fileStatusSpan.Inlines.Clear();
                        this.fileStatusSpan.Inlines.Add(new Run(header));
                        this.fileStatusSpan.Background = Brushes.Green;
                        this.fileStatusSpan.Foreground = Brushes.White;
                        this.fileStatusSpan.FontWeight = FontWeights.Bold;
                        this.fileStatusSpan.ToolTip = "进行中" + tail;

                        this.splitterSpan.Inlines.Clear();
                        this.splitterSpan.Inlines.Add(new Run(" "));
                        break;
                    }
                case "[+]":
                    {
                        this.fileStatusSpan.Inlines.Clear();
                        this.fileStatusSpan.Inlines.Add(new Run(header));
                        this.fileStatusSpan.Background = Brushes.Blue;
                        this.fileStatusSpan.Foreground = Brushes.White;
                        this.fileStatusSpan.FontWeight = FontWeights.Bold;
                        this.fileStatusSpan.ToolTip = "定稿" + tail;

                        this.splitterSpan.Inlines.Clear();
                        this.splitterSpan.Inlines.Add(new Run(" "));
                        break;
                    }
                case "[#]":
                    {
                        this.fileStatusSpan.Inlines.Clear();
                        this.fileStatusSpan.Inlines.Add(new Run(header));
                        this.fileStatusSpan.Background = Brushes.Brown;
                        this.fileStatusSpan.Foreground = Brushes.White;
                        this.fileStatusSpan.FontWeight = FontWeights.Bold;
                        this.fileStatusSpan.ToolTip = "废弃" + tail;

                        this.splitterSpan.Inlines.Clear();
                        this.splitterSpan.Inlines.Add(new Run(" "));
                        break;
                    }
                //case "[-]":
                default:
                    {
                        this.fileStatusSpan.Inlines.Clear();
                        this.fileStatusSpan.Inlines.Add(new Run("[-]"));
                        this.fileStatusSpan.Background = Brushes.Red;
                        this.fileStatusSpan.Foreground = Brushes.White;
                        this.fileStatusSpan.FontWeight = FontWeights.Bold;
                        this.fileStatusSpan.ToolTip = "未开始" + tail;

                        this.splitterSpan.Inlines.Clear();
                        this.splitterSpan.Inlines.Add(new Run(" "));
                        break;
                    }
            }
        }

        /// <summary>
        /// 当前工作区树型列表项中是否某个子项的路径与指定路径相同。
        /// </summary>
        internal bool IsSubWorkspaceTreeViewItemExists(string subPath)
        {
            if (string.IsNullOrWhiteSpace(subPath)) return false;
            if (this.HasItems == false) return false;

            foreach (var item in this.Items)
            {
                var wi = item as WorkspaceTreeViewItem;
                if (wi == null) continue;

                if (wi.IsDirectoryExists)
                {
                    var a = wi.FullPath.ToLower();
                    if (a.EndsWith("\\") == false) a += "\\";
                    if (subPath.EndsWith("\\") == false) subPath += "\\";
                    if (subPath == a) return true;
                }
                else
                {
                    var a = wi.FullPath.ToLower();
                    subPath = subPath.ToLower();
                    if (a == subPath) return true;
                }
            }

            return false;
        }

        /// <summary>
        /// 是否某个同类项目的下级项目。
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool IsSubItemOf(WorkspaceTreeViewItem item)
        {
            if (this == item) return false;
            if (this.Parent == item) return true;

            var parentItem = item;
            while (parentItem != null)
            {
                if (parentItem == item) return true;
                else parentItem = parentItem.Parent as WorkspaceTreeViewItem;
            }
            return false;
        }
    }

    /// <summary>
    /// 按名称对工作区管理器中的同级条目进行排序。
    /// </summary>
    public class WorkspaceTreeViewItemCompare : IComparer<WorkspaceTreeViewItem>
    {
        public int Compare(WorkspaceTreeViewItem x, WorkspaceTreeViewItem y)
        {
            return x.ShortName.CompareTo(y.ShortName);
        }
    }
}
